package bultin;

import java.awt.Color;

import javax.swing.AbstractButton;
import javax.swing.JComponent;
import javax.swing.text.JTextComponent;

import pseudo_ASH.MainButtonPanel;
import pseudo_ASH.MainButtonPanel.FunctionButtonListener;
import code.ObjectC;
import code.TokenType;
import code.Variable;
import code.Variable.varType;

import com.sydwell.service.ArrayPlus;
import com.sydwell.service.Helper;

/**
 * xmas Changed  super class of methods to {@link BuiltinMethod}
 * 
 * Container for all Java Object Methods
 * @author Sydwell
 *
 */
public class JavaObjectMethods {
	public static OnClick onClick;
	public static SetBackground setBackground;
	public static SetForeground setForeground;
	public static GetBackground getBackground;
	public static GetForeground getForeground;
	public static SetSelected setSelected;
	public static IsSelected isSelected;
	public static GetValue getValue;
	public static SetValue setValue;
	public static GetText getText;
	public static SetText setText;
	
	private JavaObjectMethods() {
//		super();
//		onClick = new OnClick("onClick");
//		setBackground = new SetBackground("setBackground");
//		setForeground = new SetForeground("setForeground");
//		getForeground = new GetForeground("getForeground");
//		getBackground = new GetBackground("getBackground");
//		setSelected = new SetSelected("setSelected");
//		isSelected = new IsSelected("isSelected");
//		getValue = new GetValue("getValue");
//		setValue = new SetValue("setValue");
//		getText = new GetText("getValue");
//		setText = new SetText("setValue");
	}
	
	/**
	 * Entry point for this class
	 * Called 
	 * {@link BIClass}.initializeClasses()
	 */
	public static void loadAll() {
		getBackground = new GetBackground("getBackground");
		getForeground = new GetForeground("getForeground");
		getText = new GetText("getValue");
		getValue = new GetValue("getValue");
		isSelected = new IsSelected("isSelected");
		onClick = new OnClick("onClick");
		setBackground = new SetBackground("setBackground");
		setForeground = new SetForeground("setForeground");
		setSelected = new SetSelected("setSelected");
		setValue = new SetValue("setValue");
		setText = new SetText("setValue");
	}
	
	private static class GetBackground extends BuiltinMethod  {
		public GetBackground(String newName ) {
			super(newName);
			super.setReturnType(varType.STRING);
		}
	
		@Override
		public Variable excuteMethod(ObjectC theOb, ArrayPlus<TokenType> arrayPlus) {
			Color ink = Helper.getColourOnText(arrayPlus.get(0).getTokenText());
			theOb.getJavaObject().setForeground(ink);
			return null;
		}
		
		@Override
		public String convert2Java(ArrayPlus<TokenType> arguments, TokenType target) {
			//getColor
			Helper.debug(" arguments " + arguments, true);
			return "Not Yet Implemented" + target;
		}
	
		@Override
		public String information() {
			
			return "Get the background colour";
		}
	}

	private static class GetForeground extends BuiltinMethod {
		public GetForeground(String newName ) {
			super(newName);
			//super.addParameter(varType.STRING);
			super.setReturnType(varType.STRING);
		}

		@Override
		public Variable excuteMethod(ObjectC theOb, ArrayPlus<TokenType> arrayPlus) {
			Color ink = Helper.getColourOnText(arrayPlus.get(0).getTokenText());
			theOb.getJavaObject().setForeground(ink);
			return null;
		}
		
		@Override
		public String convert2Java(ArrayPlus<TokenType> arguments, TokenType target) {
//			for (TokenType toks: arguments ){
//				
//			}
			return "Not Yet Implemented";
		}

		@Override
		public String information() {
			String out = "\n Returns the foreground colour";
			out +=	"\n Normally the foreground colour is also the colour of the text of an object";
			return out;
		}
	}
	
	private static class GetText extends BuiltinMethod {
		public GetText(String newName ) {
			super(newName);
			super.setReturnType(varType.STRING);
		}
	
		@Override
		public Variable excuteMethod(ObjectC theOb, ArrayPlus<TokenType> arrayPlus) {
			Variable var = new Variable("$builtob", TokenType.createTokenAsString("unnSet"));
			JComponent java = theOb.getJavaObject();
			String ret = null;
			if (java instanceof AbstractButton) {
				ret = ((AbstractButton) theOb.getJavaObject()).getText();
			}
			if (java instanceof JTextComponent) {
				ret = ((JTextComponent) theOb.getJavaObject()).getText();
			}
			var.setAndConvert(ret);
			return var;
		}
		
		@Override
		public String convert2Java(ArrayPlus<TokenType> arguments, TokenType target) {
			String out = "";
			for (TokenType toks: arguments ){
				//if (toks.getTokenText().equalsIgnoreCase(";")) continue;
				if (toks.getTokenText().equalsIgnoreCase("getValue")) {
					out += "getText";
				} else {
					out += toks;				}
			}
			out = out.replace(";", "");
			out = out.replace("\r", "");
			out = out.replace("\n", "");
			return out;
		}
	
		@Override
		public String information() {
			// TODO Auto-generated method stub
			return "Returns the text associated with the object";
		}
	}

	private static class GetValue extends BuiltinMethod  {
		public GetValue(String newName ) {
			super(newName);
			//super.addParameter(varType.BOOLEAN);
			super.setReturnType(varType.STRING);
		}

		@Override
		public Variable excuteMethod(ObjectC theOb, ArrayPlus<TokenType> arrayPlus) {
			Variable var = new Variable("$builtob", TokenType.createTokenAsString("unnSet"));
			JComponent java = theOb.getJavaObject();
			String ret = null;
			if (java instanceof AbstractButton) {
				ret = ((AbstractButton) theOb.getJavaObject()).getText();
			}
			if (java instanceof JTextComponent) {
				ret = ((JTextComponent) theOb.getJavaObject()).getText();
			}
			var.setAndConvert(ret);
			return var;
		}
		
		@Override
		public String convert2Java(ArrayPlus<TokenType> arguments, TokenType target) {
			// TODO To Test
			return arguments.toStringOnly();
		}

		@Override
		public String information() {
			// TODO Auto-generated method stub
			return "Returns the value associated with the object";
		}
	}	
	
	private static class IsSelected extends BuiltinMethod {
		public IsSelected(String newName ) {
			super(newName);
		}
	
		@Override
		public Variable excuteMethod(ObjectC theOb, ArrayPlus<TokenType> arrayPlus) {
			//((JCheckBox)cd.getJavaObject()).
			boolean ret = ((AbstractButton) theOb.getJavaObject()).isSelected();
			return Variable.createVariable(ret);
		}
		
		@Override
		public String convert2Java(ArrayPlus<TokenType> arguments, TokenType target) {
			// TODO Auto-generated method stub
			return "Not Yet Implemented";
		}
	
		@Override
		public String information() {
			
			return "Returns true if this object is in the selected state";
		}
	}

	private static class OnClick extends BuiltinMethod  {
		public OnClick(String newName) {
			super(newName);
			super.addParameter(varType.ANY_TYPE);
			
		}
	
		@Override
		public Variable excuteMethod(ObjectC theOb, ArrayPlus<TokenType> arrayPlus) {
			//Helper.debug(" Variable out ");
			FunctionButtonListener acts = new MainButtonPanel.FunctionButtonListener();
			acts.setEnv(arrayPlus.get(0).getTokenText());
			((AbstractButton) theOb.getJavaObject()).addActionListener(acts);
			return null;
		}
		
		@Override
		public String convert2Java(ArrayPlus<TokenType> arguments, TokenType target) {
			// TODO Auto-generated method stub
			return "Not Yet Implemented";
		}
	
		@Override
		public String information() {
			String out = "Specifies the supplied function to execute on this object is clicked";
			out += "\nExample: mybutton.onClick(myfunction)";
			out += "\nWhere: mybutton belongs to a class that implements this onClick method such as the Button class";
			out += "\nWhere: myfunction is a previously defined function";
			return out;
		}
	}

	private static class SetBackground extends BuiltinMethod  {
		public SetBackground(String newName ) {
			super(newName);
			//super.setReturnType(varType.INTEGER);
			super.addParameter(varType.STRING);	
		}
	
		@Override
		public Variable excuteMethod(ObjectC theOb, ArrayPlus<TokenType> arrayPlus) {
			Color ink = Helper.getColourOnText(arrayPlus.get(0).getTokenText());
			theOb.getJavaObject().setBackground(ink);
			return null;
		}
		@Override
		public String convert2Java(ArrayPlus<TokenType> arguments, TokenType target) {
			//plusOp_b.setBackground( Color.getColor("YELLOW"));
			String out = arguments.get(0) + ".setBackground( Color.getColor(" + target + "))";
	
			out = out.replace(";", "");
			out = out.replace("\r", "");
			out = out.replace("\n", "");
			return out;
		}
	
		@Override
		public String information() {
			return "Sets the background colour of this object";
		}
	}

	private static class SetForeground extends BuiltinMethod  {
		public SetForeground(String newName ) {
			super(newName);
			super.addParameter(varType.STRING);
		}
	
		@Override
		public Variable excuteMethod(ObjectC theOb, ArrayPlus<TokenType> arrayPlus) {
			Color ink = Helper.getColourOnText(arrayPlus.get(0).getTokenText());
			theOb.getJavaObject().setForeground(ink);
			return null;
		}
		
		@Override
		public String convert2Java(ArrayPlus<TokenType> arguments, TokenType target) {
			//plusOp_b.setForeground( Color.getColor("YELLOW"));
			String out = arguments.get(0) + ".setForeground( Color.getColor(" + target + "))";
	
			out = out.replace(";", "");
			out = out.replace("\r", "");
			out = out.replace("\n", "");
			return out;
		}
	
		@Override
		public String information() {
			String out = "Sets the foreground colour of this object";
			out +=	"\n Normally the foreground colour is also the colour of the text of an object";
			return out;
		}
	}

	private static class SetSelected extends BuiltinMethod {
		public SetSelected(String newName ) {
			super(newName);
			super.addParameter(varType.STRING);
			
		}
	
		@SuppressWarnings("boxing")
		@Override
		public Variable excuteMethod(ObjectC theOb, ArrayPlus<TokenType> arrayPlus) {
			//((JCheckBox)cd.getJavaObject()).
			((AbstractButton) theOb.getJavaObject()).setSelected(Boolean.valueOf(arrayPlus.get(0).getTokenText()));
			return null;
		}
		
		@Override
		public String convert2Java(ArrayPlus<TokenType> arguments, TokenType target) {
			// radio2.setSelected( true );
			String out = arguments.get(0) + ".setSelected( " + target + ")";
	
			out = out.replace(";", "");
			out = out.replace("\r", "");
			out = out.replace("\n", "");
			return out;
		}
	
		@Override
		public String information() {
			
			return "Put the object in a selected state";
		}
	}

	private static class SetText extends BuiltinMethod {
		public SetText(String newName ) {
			super(newName);
			super.addParameter(varType.STRING);
		}
	
		@Override
		public Variable excuteMethod(ObjectC theOb, ArrayPlus<TokenType> arrayPlus) {
			JComponent java = theOb.getJavaObject();
			Variable vt = arrayPlus.get(0).getTokenVariable();
			if (java instanceof AbstractButton) {
				((AbstractButton) theOb.getJavaObject()).setText("" + vt.getValue());
			}
			if (java instanceof JTextComponent) {
				((JTextComponent) theOb.getJavaObject()).setText("" + vt.getValue());
			}
			return null;
		}
		
		@Override
		public String convert2Java(ArrayPlus<TokenType> arguments, TokenType target) {
			String out = "";
			for (TokenType toks: arguments ){
				//if (toks.getTokenText().equalsIgnoreCase(";")) continue;
				if (toks.getTokenText().equalsIgnoreCase("setValue")) {
					out += "setText";
				} else {
					out += toks;				}
			}
			out = out.replace(";", "");
			out = out.replace("\r", "");
			out = out.replace("\n", "");
			return out;
		}
	
		@Override
		public String information() {
			String out = "Will set the text of the object";
			out += "\nUsage:" ;
			out += "<object>.setText(<new_text>)";
			out += "\nWhere: <object> is the object whase value will be set";
			out += "\nWhere: <new_text> is the new text to the object";
			return out;
		}
	}

	private static class SetValue extends BuiltinMethod {
		public SetValue(String newName ) {
			super(newName);
			super.addParameter(varType.STRING);
		}

		@Override
		public Variable excuteMethod(ObjectC theOb, ArrayPlus<TokenType> arrayPlus) {
			JComponent java = theOb.getJavaObject();
			Variable vt = arrayPlus.get(0).getTokenVariable();
			if (java instanceof AbstractButton) {
				((AbstractButton) theOb.getJavaObject()).setText("" + vt.getValue());
			}
			if (java instanceof JTextComponent) {
				((JTextComponent) theOb.getJavaObject()).setText("" + vt.getValue());
			}
			return null;
		}
		
		@Override
		public String convert2Java(ArrayPlus<TokenType> arguments, TokenType target) {
			// TODO To Test
			return arguments.toStringOnly();
		}

		@Override
		public String information() {
			String out = "Will set the value of the object";
			out += "\nUsage:" ;
			out += "<object>.setValue(<new_value>)";
			out += "\nWhere: <object> is the object whase value will be set";
			out += "\nWhere: <new_value> is the new value to the object";
			return out;
		}
	}

	
}
